#include <Arduino.h>
#include "myModbusRTUSlave.h"
#include "myEEPROM.h"
#include "myPressure.h"
#include "myFlowSensor.h"
#include "myDistance.h"


uint64_t timeRecord;       // 当前时间记录
uint16_t interval = 500;  // 间隔时间
int mbsSlaveID = 1;        // modbus从站地址号
uint32_t comRate = 115200; // modbus波特率

/*
IIC引脚
SDA = 8;
SCL = 9;
*/
/// @brief 处理ModbusRTU通信任务
/// @param parameterg
void ModbusRTUTask(void *parameter)
{
  while (true)
  {
    DoModbusRTU();
    vTaskDelay(pdMS_TO_TICKS(1)); // 1ms延迟;
  }
}

void setup()
{
  /*串口初始化*/
  Serial.begin(115200);
  /*打印Flash大小和PSRAM是否启用*/
  Serial.print("Flash size:");
  Serial.println(ESP.getFlashChipSize());
  Serial.print("PSRAM:");
  Serial.println(ESP.getPsramSize());
  Serial.print("FreeRAM:");
  Serial.println(ESP.getFreePsram());

  /*打印一当前芯片内置温度传感器温度*/
  Serial.print("Temperature:");
  Serial.println(temperatureRead());
  Serial.print("SerialConfig:");
  delay(1000);

  Wire.begin(); // 初始化I2C总线
  // Serial.begin(115200);                     // 初始化串口通信
  ReadParameter();      // 加载EEPROM参数到保持寄存器中
  DistanceInitialize(); // 距离传感器初始化
  // ModbusRTU初始化
  ModbusRTUInitialize(mbsSlaveID, comRate);

  //  /*将RGB闪烁任务分配在核心0上*/
  //  xTaskCreatePinnedToCore(RGB_Flash_Task,       // 多任务调用的函数名称
  //                          "RGB_Flash_Function", // 这个任务的名字
  //                          1024 * 5,             // 任务的堆栈大小,分配了5k堆栈
  //                          NULL,                 // 任务的参数
  //                          1,                    // 任务的参数
  //                          NULL,                 // 跟踪创建任务的任务句柄
  //                          0                     // 将任务分配在哪个核心上,主核心是core1，core0是辅助核心
  //  );
  //  /*将web服务任务分配在核心0上*/
  //  xTaskCreatePinnedToCore(WebService_Task,         // 多任务调用的函数名称
  //                          "WIFI_Service_Function", // 这个任务的名字
  //                          1024 * 50,               // 任务的堆栈大小,分配了50k堆栈
  //                          NULL,                    // 任务的参数
  //                          1,                       // 任务的参数
  //                          NULL,                    // 跟踪创建任务的任务句柄
  //                          0                        // 将任务分配在哪个核心上,主核心是core1，core0是辅助核心
  //  );
  //  /*将模拟键盘的发送任务分配在核心1上*/
  //  xTaskCreatePinnedToCore(KeyboardProcessTask, // 多任务调用的函数名称
  //                          "Keyboard_Function", // 这个任务的名字
  //                          1024 * 20,           // 任务的堆栈大小,分配了20k堆栈
  //                          NULL,                // 任务的参数
  //                          1,                   // 任务的参数
  //                          NULL,                // 跟踪创建任务的任务句柄
  //                          1                    // 将任务分配在哪个核心上,主核心是core1，core0是辅助核心
  //  );
  /*将按钮处理任务任务分配在核心1上*/
  xTaskCreatePinnedToCore(ModbusRTUTask,   // 多任务调用的函数名称
                          "ModbusRTUTask", // 这个任务的名字
                          1024 * 10,       // 任务的堆栈大小,分配了10k堆栈
                          NULL,            // 任务的参数
                          1,               // 任务的参数
                          NULL,            // 跟踪创建任务的任务句柄
                          0                // 将任务分配在哪个核心上,主核心是core1，core0是辅助核心
  );
}

void loop()
{
  vTaskDelay(1);
  if (millis() - timeRecord >= interval) // 执行一次数据刷新
  {
    timeRecord = millis();
    // digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    //  ShowPressureValue();   // 显示压力值
    //  ShowFlowSensorValue(); // 显示流量值
    //  ShowDistanceValue();   // 显示距离值
    holdingRegisters[0] = GetPressureValue(0);
    holdingRegisters[1] = GetPressureValue(1);
    holdingRegisters[2] = GetPressureValue(2);
    holdingRegisters[3] = GetPressureValue(3);
    holdingRegisters[4] = GetPressureValue(4);
    holdingRegisters[5] = GetFlowSensor();
    holdingRegisters[6] = GetDistance();
    holdingRegisters[7] = (uint16_t)(millis() - timeRecord);  // 读取数据耗时
    holdingRegisters[10] = (millis() / 1000ul) / 60 / 60;     // 显示小时
    holdingRegisters[11] = (((millis() / 1000ul) / 60) % 60); // 显示分钟
    holdingRegisters[12] = (millis() / 1000ul) % 60;          // 显示秒
    holdingRegisters[13] = millis() % 1000ul;                 // 显示毫秒
    holdingRegisters[8] ^= 0X0100;
    // Serial.print("All:");
    // Serial.println((uint32_t)(millis() - timeRecord));
  }

  // 参数功能,只要holdingRegisters[19]不等于0，
  if (holdingRegisters[19] != 0)
  {
    if (holdingRegisters[19] == 0x0010) // =0x10初始化参数
    {
      ParameterInitialize(); // 初始化参数
    }
    else if (holdingRegisters[19] == 0x0001) // =0x01保存参数
    {
      SaveParameter(); // 保存参数
    }
    else if (holdingRegisters[19] == 0x0002) // =0x02重新加载参数
    {
      ReadParameter(); // 重新加载参数
    }
    holdingRegisters[19] = 0;
  }

  // digitalWrite(LED_BUILTIN, holdingRegisters[8] & 0X0001);
}
